import React from "react";
import { useParams } from "react-router-dom";
import { useDispatch, useState } from "../../components/RootProvider";
import { IPSetInfo, IPSetRule } from "../../api/types";
import { LoadingModal } from "../../components/Loading";
import styles from "./IPSetDetailsPage.module.css";
import { addIPSetRule, checkRule, deleteIPSetRule } from "../../api/ipset";
import RuleModal from "./RuleModal";

function useIPSetInfo(setname: string = ""): IPSetInfo | null {
  const { ipsetInfo } = useState();
  return ipsetInfo[setname];
}

interface RuleItemProps {
  rule: IPSetRule;
  time: number;
  onClickDelete: (rule: IPSetRule) => void;
  onClickEdit: (rule: IPSetRule) => void;
}

const RuleItem = React.memo(
  ({
    rule,
    time,
    onClickDelete: _onClickDelete,
    onClickEdit: _onClickEdit,
  }: RuleItemProps) => {
    const onClickDelete = React.useCallback(() => {
      _onClickDelete(rule);
    }, [_onClickDelete, rule]);

    const onClickEdit = React.useCallback(() => {
      _onClickEdit(rule);
    }, [_onClickEdit, rule]);

    const timeLabel = React.useMemo(() => {
      if(rule.timeout <= 0){
        return '永不'
      }
      return new Date((time + rule.timeout) * 1000).toLocaleString()
    },[rule.timeout, time])

    return (
      <div className={styles.row}>
        <div className={styles.ip}>{rule.ip}</div>
        <div className={styles.timeout}>
          {timeLabel}
        </div>
        <div className={styles.remarks}>{rule.remarks}</div>
        <div className={styles.actions}>
          <button onClick={onClickEdit}>修改</button>
          <button onClick={onClickDelete}>删除</button>
        </div>
      </div>
    );
  },
  (pre, next) => {
    return (
      pre.time === next.time &&
      pre.rule.ip === next.rule.ip &&
      pre.rule.timeout === next.rule.timeout
    );
  }
);

const IPSetDetailsPage: React.FC = () => {
  const ruleModalRef = React.useRef<RuleModal>(null);
  const [loading, setLoading] = React.useState(true);
  const { setname } = useParams();
  const { refreshIPSetInfo } = useDispatch();
  const ipsetInfo = useIPSetInfo(setname);
  const { user } = useState();

  const onClickDelete = React.useCallback(
    async (rule: IPSetRule) => {
      const flag = window.confirm(`是否确定要删除 IP: ${rule.ip}`);
      if (!flag) {
        return;
      }
      setLoading(true);
      const res = await deleteIPSetRule(setname || "", rule);
      await refreshIPSetInfo(setname || "");
      setLoading(false);

      if (!res) {
        window.alert("删除失败");
      }
    },
    [refreshIPSetInfo, setname]
  );

  const onClickEdit = React.useCallback((rule: IPSetRule) => {
    ruleModalRef.current?.edit({ rule: rule });
  }, []);

  const onClickAdd = React.useCallback(() => {
    ruleModalRef.current?.add({});
  }, []);

  const onSave = React.useCallback(
    async (data: { type: "add" | "edit"; rule: IPSetRule }) => {
      const isValid = checkRule(data.rule);
      if (isValid) {
        alert(isValid);
        return false;
      }
      setLoading(true);
      const res = await addIPSetRule(setname || "", data.rule);
      await refreshIPSetInfo(setname || "");
      setLoading(false);
      if (!res) {
        alert("保存失败");
      }
      return res;
    },
    [refreshIPSetInfo, setname]
  );

  React.useEffect(() => {
    refreshIPSetInfo(setname || "").finally(() => {
      setLoading(false);
    });
  }, [refreshIPSetInfo, setname]);

  if (!ipsetInfo) {
    return (
      <div className={styles.details}>
        {loading ? (
          <LoadingModal />
        ) : (
          <div>
            <h2>加载数据失败</h2>
            <p>请在服务器上执行以下命令检测是否存在规则 {setname}</p>
            <code>ipset list {setname}</code>
            <p>如果不存在,请在服务器上执行以下命令创建规则 {setname}</p>
            <code>ipset create {setname} hash:ip timeout 86400 comment</code>
          </div>
        )}
      </div>
    );
  }

  return (
    <div className={styles.details}>
      <RuleModal
        ref={ruleModalRef}
        defaultTimeout={ipsetInfo.timeout}
        currentNetworkIP={user?.ipv4}
        supportedRemarks={ipsetInfo.remarks}
        onSave={onSave}
      />
      {loading ? <LoadingModal /> : null}
      <div className={styles.header}>
        <div>
          <span>名称:</span>
          <span>{ipsetInfo.name}</span>
        </div>
        <div>
          <span>默认超时:</span>
          <span>{ipsetInfo.timeout > 0 ? `${ipsetInfo.timeout} 秒`: '永不'} </span>
        </div>
        <div>
          <span>规则数量:</span>
          <span>{ipsetInfo.rules.length}</span>
        </div>

        <div>
          <span>最大规则数量:</span>
          <span>{ipsetInfo.max_rules}</span>
        </div>
        <div>
          <span>规则支持备注: </span>
          <span>{ipsetInfo.remarks ? "是" : "否"}</span>
        </div>
        <div>
          <span>获取时间:</span>
          <span>{new Date(ipsetInfo.time * 1000).toLocaleString()}</span>
        </div>
      </div>
      <div className={styles.main}>
        <div className={styles.actionRow}>
          <button onClick={onClickAdd}>添加规则</button>
        </div>
        <div className={`${styles.row} ${styles.rowHeader}`}>
          <div className={styles.ip}>IP</div>
          <div className={styles.timeout}>失效时间</div>
          <div className={styles.remarks}>备注</div>
          <div className={styles.actions}>操作</div>
        </div>
        <div className={styles.values}>
          {ipsetInfo.rules.map((rule) => (
            <RuleItem
              key={rule.ip}
              rule={rule}
              time={ipsetInfo.time}
              onClickDelete={onClickDelete}
              onClickEdit={onClickEdit}
            />
          ))}
        </div>
      </div>
    </div>
  );
};

export { IPSetDetailsPage };
